######################################
#Calculate MSY--------------------------------------------------
#This code runs CatchMSY on fisheries
######################################
# SnowCatchMSY<- function(s)
MatrixSnowCatchMSY<- function(s,Data,CommonError,CommonRange,sigR,Smooth,Display,BestValues,ManualFinalYear,n,NumCPUs,CatchMSYTrumps,stock_id,IdVar)
{
RanCMSY<- FALSE
require(zoo)
require(plyr)
MatrixCmsy<- function(parbound,n,interbio,finalbio,startbt)
{
with(as.list(parbound),
{
gi = rep(exp(runif(n, log(start_g[1]), log(start_g[2]))),length(startbt)) ## get N values between g[1] and g[2], assign to ri
ki = rep(exp(runif(n, log(start_k[1]), log(start_k[2]))),length(startbt)) ## get N
startbti<- sort(rep(startbt,n))
ParamSpace<- as.data.frame(cbind(phi,gi,ki,interbio[1],interbio[2],finalbio[1],finalbio[2],sigR,startbti))
colnames(ParamSpace)<- c('phi','g','K','InterBio1','InterBio2','FinalBio1','FinalBio2','sigR','StartBio')
# bvbmsyell<- rep(0,length(bt))
# if(bt[nyr]/k>=lam1 && bt[nyr]/k <=lam2 && min(bt,na.rm=T) > 0 && max(bt,na.rm=T) <=k && bt[which(yr==interyr)]/k>=interbio[1] && bt[which(yr==interyr)]/k<=interbio[2])
# {ell = 1
# bvbmsyell<-rep(1,length(bt))
# }
CatchMat<- matrix(rep(ct,dim(ParamSpace)[1]),nrow=dim(ParamSpace)[1],ncol=length(ct),byrow=T)
btMat<- matrix(NA,nrow=dim(CatchMat)[1],dim(CatchMat)[2])
btMat[,1]<- ParamSpace$K*ParamSpace$StartBio*exp(rnorm(1,0, ParamSpace$sigR))
xt<- rnorm(1,0, sigR)
for (y in 2:length(ct))
{
# btMat[,y]<- btMat[,y-1]+ParamSpace$r*btMat[,y-1]*(1-btMat[,y-1]/ParamSpace$K)-ct[y-1]*exp(xt)
btMat[,y]<- btMat[,y-1]+((phi+1)/phi)*ParamSpace$g*btMat[,y-1]*(1-(btMat[,y-1]/ParamSpace$K)^phi)-ct[y-1]*exp(xt)
}
ItId<- 1:dim(btMat)[1]
ResultMat<- data.frame(ItId,btMat,ParamSpace)
BioDat<- ResultMat[,grepl('X',colnames(ResultMat))]
interyr<- round(median(1:nyr))
EllBio<- data.frame(apply(BioDat,1,min),apply(BioDat,1,max),BioDat[,interyr]/ResultMat$K,BioDat[,nyr]/ResultMat$K)
colnames(EllBio)<- c('MinBio','MaxBio','InterBio','FinalBio')
# Ell= EllBio$FinalBio>=ResultMat$FinalBio1 & EllBio$FinalBio <= ResultMat$FinalBio2 & EllBio$InterBio>=ResultMat$InterBio1 & EllBio$InterBio <= ResultMat$InterBio2 & EllBio$MinBio>0 & EllBio$MaxBio<ResultMat$K
Ell= ResultMat$StartBio==min(ResultMat$StartBio) & EllBio$FinalBio>=ResultMat$FinalBio1 & EllBio$FinalBio <= ResultMat$FinalBio2 & EllBio$InterBio>=ResultMat$InterBio1 & EllBio$InterBio <= ResultMat$InterBio2 & EllBio$MinBio>0 & EllBio$MaxBio<ResultMat$K
Missing<- is.na(EllBio$FinalBio)
PossibleRuns<- ResultMat[Ell & !Missing,]
return(PossibleRuns)
})
}
stock<- (stock_id[s])
Data<- Data[Data$IdOrig==stock,]
BtoKRatio<- unique(Data$BtoKRatio)
CatchYears<- (Data$Year*as.numeric(is.na(Data$Catch)==F))
CatchYears[CatchYears==0]<- NA
FirstCatchYear<- which(Data$Year==min(CatchYears,na.rm=T))[1]
LastCatchYear<- which(Data$Year==max(CatchYears,na.rm=T))[1]
Data<- Data[FirstCatchYear:LastCatchYear,]
if (any(Data$HasRamFvFmsy))
{
RamFvFmsy<- Data$FvFmsy
}
Where<- Data[,IdVar]==stock
# (paste(round(100*(s/length(stock_id)),2),'% done with CatchMSY',sep=''))
write.table((paste(round(100*(s/length(stock_id)),2),'% done with CatchMSY',sep='')), file = 'CatchMSY Progress.txt', append = TRUE, sep = ";", dec = ".", row.names = FALSE, col.names = FALSE)
yr <- Data$Year[(Data[,IdVar])==stock]
ct <- (Data$Catch[(Data[,IdVar])==stock]) ## assumes that catch is given in tonnes, transforms to 1'000 tonnes
# bio<- pmin(1,Data$BvBmsy[Data[,IdVar]==stock]/2) #pull out bvbmsy (transposed to B/K)
bio<- pmin(1,(Data$BvBmsy*Data$BtoKRatio)[Data[,IdVar]==stock]) #pull out bvbmsy (transposed to B/K)
bioerror<- (Data$BvBmsySD*Data$BtoKRatio)[Where]
# bioerror<- bioerror*1.4
bioerror[is.na(bioerror)]<- CommonError
PossibleRuns<- NA
if (sum(ct,na.rm=T)>0 & sum(bio,na.rm=T)>0 & length(LastCatchYear)>0 & length(ct)>1)
{
ct<- na.approx(ct)
if(Smooth==1){ct<- runmed(ct,3)}
res <- (Data$Res[(Data[,IdVar])==stock])[1] ## resilience from FishBase, if needed, enable in PARAMETER SECTION
if(is.na(res)){res<- 0.5}
for (i in 1){
start_g <- if(res == "Very low"){c(0.001, 0.05)}
else if(res == "Low") {c(0.05,0.15)}
else if(res == "Medium") {c(0.15,0.5)}
else if(res == "High") {c(0.5,1)}
else {c(0.15,0.5)} ## Medium, or default if no res is found
}
phi<- unique(Data$phi)
start_g<- start_g*(phi/(1+phi)) #To account for g instead of r
nyr <- length(yr) ## number of years in the time series
# cat("\n","Stock",stock,"\n")
flush.console()
## PARAMETER SECTION
start_k <- c(max(ct,na.rm=T),50*max(ct,na.rm=T)) ## default for upper k e.g. 100 * max catch
startbio <- c(0.6,1) ## assumed biomass range at start of time series, as fraction of k
# startbio <- pmin(1,pmax(0,c(qnorm(0.45,bio[1],bioerror[1]),qnorm(0.55,bio[1],bioerror[1]))))
# startbio <- pmin(1,c((1-ErrorSize)*bio[1],(1+ErrorSize)*bio[1]))
if (is.na(bio[1]) | bio[1]==0)
{
startbio <- if(ct[1]/max(ct,na.rm=T) < 0.5) {c(0.5,0.9)} else {c(0.3,0.6)} ## use for batch processing #SUB IN BVBMSY VALUES
}
interyr <- median(1:length(yr)) ## interim year within time series for which biomass estimate is available; set to yr[2] if no estimates are available #SUB IN INTERMIN YEAR
# interbio <- pmin(1,c((1-ErrorSize)*bio[interyr],(1+ErrorSize)*bio[interyr])) ## biomass range for interim year, as fraction of k; set to 0 and 1 if not available
# interbio <- pmin(1,pmax(0,c(qnorm(0.45,bio[interyr],bioerror[interyr]),qnorm(0.55,bio[interyr],bioerror[interyr])))) ## biomass range for interim year, as fraction of k; set to 0 and 1 if not available
interbio <- c(0, 1) ## biomass range for interim year, as fraction of k; set to 0 and 1 if not available
if (is.na(bio[interyr]) | bio[interyr]==0)
{
interbio <- c(0, 1) ## biomass range for interim year, as fraction of k; set to 0 and 1 if not available
}
interyr<- yr[interyr]
# finalbio <- pmin(1,c((1-ErrorSize)*bio[nyr],(1+ErrorSize)*bio[nyr]))
finalbio <- pmin(1,pmax(0,c(qnorm(0.45,bio[nyr],bioerror[nyr]),qnorm(0.55,bio[nyr],bioerror[nyr]))))
if(bio[nyr]>=0.95) # if final stock bio is 2 or higher set priors to BvBmsy 1.4-1.7
{
finalbio<-c(0.7,0.85)
}
if (is.na(bio[nyr]) | bio[nyr]==0)
{
finalbio <- if(ct[nyr]/max(ct,na.rm=T) > 0.5) {c(0.3,0.7)} else {c(0.01,0.4)} ## use for batch processing #SET TO KNOWN B/BMSY RANGE
}
# sigR <- 0.0 ## process error; 0 if deterministic model; 0.05 reasonable value? 0.2 is too high
startbt <- seq(startbio[1], startbio[2], length.out = 10) ## apply range of start biomass in steps of 0.05
# startbt <- seq(startbio[1], startbio[2], by = 0.05) ## apply range of start biomass in steps of 0.05
parbound <- list(g = start_g, k = start_k, lambda = finalbio, sigR=sigR,phi=unique(Data$phi))
if (Display==1)
{
cat("Last year =",max(yr),", last catch =",ct[nyr],"\n")
cat("Resilience =",res,"\n")
cat("Process error =", sigR,"\n")
cat("Assumed initial biomass (B/k) =", startbio[1],"-", startbio[2], " k","\n")
cat("Assumed intermediate biomass (B/k) in", interyr, " =", interbio[1],"-",interbio[2]," k","\n")
cat("Assumed final biomass (B/k) =", parbound$lambda[1],"-",parbound$lambda[2]," k","\n")
cat("Initial bounds for g =", parbound$g[1], "-", parbound$g[2],"\n")
cat("Initial bounds for k =", format(parbound$k[1], digits=3), "-", format(parbound$k[2],digits=3),"\n")
}
flush.console()
## MAIN
PossibleRuns<- MatrixCmsy(parbound,n,interbio,finalbio,startbt)
## Get statistics on g, k, MSY and determine new bounds for g and k
g1 <- PossibleRuns$g
k1 <- PossibleRuns$K
# msy1 <- r1*k1/4
# mean_msy1 <- exp(mean(log(msy1)))
# max_k1a <- min(k1[r1<1.1*parbound$r[1]],na.rm=T) ## smallest k1 near initial lower bound of r
# max_k1b <- max(k1[r1*k1/4<mean_msy1],na.rm=T) ## largest k1 that gives mean MSY
# max_k1 <- if(max_k1a < max_k1b) {max_k1a} else {max_k1b}
if(length(g1)<10)
{
finalbio<- pmax(0,pmin(1,finalbio+c(-.065,.065)))
PossibleRuns<- MatrixCmsy(parbound,n,interbio,finalbio,startbt)
## Get statistics on g, k, MSY and determine new bounds for g and k
g1 <- PossibleRuns$g
k1 <- PossibleRuns$K
}
if(length(g1)<10) {
cat("Too few (", length(g1), ") possible g-k combinations, check input parameters","\n")
flush.console()
}
if(length(g1)>=10) {
msy1 <- (g1*k1)*BtoKRatio
mean_msy1 <- exp(mean(log(msy1)))
max_k1a <- min(k1[g1<1.1*parbound$g[1]],na.rm=T) ## smallest k1 near initial lower bound of g
max_k1b <- max(k1[(g1*k1)*BtoKRatio <mean_msy1],na.rm=T) ## largest k1 that gives mean MSY
max_k1 <- if(max_k1a < max_k1b) {max_k1a} else {max_k1b}
## set new upper bound of g to 1.2 max r1
parbound$g[2] <- 1.2*max(g1)
## set new lower bound for k to 0.9 min k1 and upper bound to max_k1
parbound$k <- c(0.9 * min(k1), max_k1)
if (Display==1)
{
cat("First MSY =", format(mean_msy1, digits=3),"\n")
cat("First g =", format(exp(mean(log(g1))), digits=3),"\n")
cat("New upper bound for g =", format(parbound$g[2],digits=2),"\n")
cat("New range for k =", format(parbound$k[1], digits=3), "-", format(parbound$k[2],digits=3),"\n")
}
## Repeat analysis with new g-k bounds
PossibleRuns<- MatrixCmsy(parbound,n,interbio,finalbio,startbt)
PossibleRuns$Fail<- 0
PossibleRuns$IdOrig<- stock
## Get statistics on g, k and msy
g <- PossibleRuns$g
k <- PossibleRuns$K
PossibleRuns$MSY<- (g*k)*BtoKRatio
bvbmsy<- (PossibleRuns[,grepl('X',colnames(PossibleRuns))]/k)/BtoKRatio
CatchMat=matrix(rep(ct,dim(PossibleRuns)[1]),nrow=dim(PossibleRuns)[1],ncol=length(ct),byrow=T)
fvfmsy<- CatchMat/PossibleRuns$MSY/bvbmsy
PossibleRuns$FinalFvFmsy<- fvfmsy[,dim(fvfmsy)[2]]
PossibleRuns$FinalBvBmsy<- bvbmsy[,dim(bvbmsy)[2]]
time_bvbmsy<- (apply(bvbmsy,2,function(x) exp(mean(log(x)))))
mean_bvbmsy<- mean(apply(bvbmsy,1,function(x) exp(mean(log(x)))))
LogSD_bvbmsy<- mean(apply(bvbmsy,1,function(x) (sd(log(x)))))
msy = (g * k) * BtoKRatio
Fmsy<- g
mean_ln_msy = mean(log(msy),na.rm=T)
mean_ln_g<- mean(log(g),na.rm=T)
mean_ln_k<- mean(log(k),na.rm=T)
# Data$MSY[Where]<- mean(msy,na.rm=T)
Data$RanCatchMSY[Where]<- TRUE
Data$MSY[Where]<- exp(mean_ln_msy)
Data$g[Where]<- exp(mean_ln_g)
Data$k[Where]<- exp(mean_ln_k)
Data$MSYLogSd[Where]<- (sd(log(msy)))
Data$gLogSd[Where]<- (sd(log(g),na.rm=T))
Data$KLogSd[Where]<- (sd(log(k),na.rm=T))
Data$CatchMSYBvBmsy[Where]<- time_bvbmsy
if (CatchMSYTrumps==T)
{
Data$BvBmsy[Where]<- time_bvbmsy
}
Data$CatchMSYBvBmsy_LogSd[Where]<- LogSD_bvbmsy
Data$FvFmsy[Where]<- (Data$Catch[Where]/Data$MSY[Where])/Data$BvBmsy[Where]
## plot MSY over catch data
if (NumCPUs==1 & length(g)>10)
{
par(mfcol=c(2,3))
plot(yr, ct, type="l", ylim = c(0, max(ct)), xlab = "Year", ylab = "Catch (MT)", main = stock)
abline(h=exp(mean(log(msy))),col="red", lwd=2)
abline(h=exp(mean_ln_msy - 2 * sd(log(msy))),col="red")
abline(h=exp(mean_ln_msy + 2 * sd(log(msy))),col="red")
hist(g, freq=F, xlim=c(0, 1.2 * max(g,na.rm=T)), main = "")
abline(v=exp(mean(log(g))),col="red",lwd=2)
abline(v=exp(mean(log(g))-2*sd(log(g))),col="red")
abline(v=exp(mean(log(g))+2*sd(log(g))),col="red")
plot(g1, k1, xlim = start_g, ylim = start_k, xlab="g", ylab="k (MT)")
hist(k, freq=F, xlim=c(0, 1.2 * max(k)), xlab="k (MT)", main = "")
abline(v=exp(mean(log(k))),col="red", lwd=2)
abline(v=exp(mean(log(k))-2*sd(log(k))),col="red")
abline(v=exp(mean(log(k))+2*sd(log(k))),col="red")
plot(log(g), log(k),xlab="ln(g)",ylab="ln(k)")
abline(v=mean(log(g)))
abline(h=mean(log(k)))
abline(mean(log(msy))+log(4),-1, col="red",lwd=2)
abline(mean(log(msy))-2*sd(log(msy))+log(4),-1, col="red")
abline(mean(log(msy))+2*sd(log(msy))+log(4),-1, col="red")
hist(msy, freq=F, xlim=c(0, 1.2 * max(c(msy))), xlab="MSY (MT)",main = "")
abline(v=exp(mean(log(msy))),col="red", lwd=2)
abline(v=exp(mean_ln_msy - 2 * sd(log(msy))),col="red")
abline(v=exp(mean_ln_msy + 2 * sd(log(msy))),col="red")
}
if (Display==1)
{
cat("Possible combinations = ", length(g),"\n")
cat("geom. mean g =", format(exp(mean(log(g))),digits=3), "\n")
cat("g +/- 2 SD =", format(exp(mean(log(g))-2*sd(log(g))),digits=3),"-",format(exp(mean(log(g))+2*sd(log(g))),digits=3), "\n")
cat("geom. mean k =", format(exp(mean(log(k))),digits=3), "\n")
cat("k +/- 2 SD =", format(exp(mean(log(k))-2*sd(log(k))),digits=3),"-",format(exp(mean(log(k))+2*sd(log(k))),digits=3), "\n")
cat("geom. mean MSY =", format(exp(mean(log(msy))),digits=3),"\n")
cat("MSY +/- 2 SD =", format(exp(mean_ln_msy - 2 * sd(log(msy))),digits=3), "-", format(exp(mean_ln_msy + 2 * sd(log(msy))),digits=3), "\n")
}
# bio<- bio*2 #Replace B/K with B/Bmsy
#
# FvFmsy<- (ct[length(ct)])/(bio[length(bio)]*msy)
#
# RealRuns<- length(r)
RanCMSY<- TRUE
} #Close if r1 is greater than 10
} #Close if there is catch loop
# Data$r[is.na(Data$r)]<- mean(Data$r,na.rm=T)
if (any(Data$HasRamFvFmsy))
{
Data$FvFmsy<- RamFvFmsy
}
# if(NumCPUs>1)
# {
# sfCat(paste(round(100*(s/length(stock_id))),'% Done',sep="\n"))
# }
# return(list(CatchMSY=Data,RanCatchMSY=RanCMSY))
return(list(CatchMSY=Data,RanCatchMSY=RanCMSY,PossibleParams=PossibleRuns))
} #Close function
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.